package com.ydlclass.ChannelHandler.handler.InboundHandler;

import com.ydlclass.Transport.message.MessageFormatConstant;
import com.ydlclass.Transport.message.Request.RequestPayload;
import com.ydlclass.Transport.message.Request.YrpcRequest;
import com.ydlclass.Transport.message.Response.YrpcResponse;
import com.ydlclass.compress.Compress;
import com.ydlclass.compress.CompressFactory;
import com.ydlclass.enumeration.RequestTypeEnum;
import com.ydlclass.enumeration.ResponseCodeEnum;
import com.ydlclass.serialize.Serialize;
import com.ydlclass.serialize.SerializerFactory;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToMessageDecoder;
import lombok.extern.slf4j.Slf4j;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.util.List;

/**
 * YrpcResponse响应解码器
 * @Author duWenJian
 * @Date 2024/2/21 20:43
 * @Version 1.0
 */
@Slf4j
public class YrpcMessageResponseDecoderHandler extends MessageToMessageDecoder<ByteBuf> {
    @Override
    protected void decode(ChannelHandlerContext ctx, ByteBuf msg, List<Object> out) {
        //既然重写了decode方法，一定不要忘了最后加入list链表中，不然很麻烦
        // 1、 解析魔术值 4字节 , 校验魔术值
        byte [] magic = new byte[MessageFormatConstant.MAGIC.length];
        msg.readBytes(magic);
        for (int i = 0; i < magic.length; i++) {
            if (magic[i] != MessageFormatConstant.MAGIC[i]){
                throw new RuntimeException("获得响应魔术值不合法!!!");
            }
        }
        // 2、解析版本号 1字节 , 校验版本号
        byte Version_Id = msg.readByte();
        if (Version_Id > MessageFormatConstant.VERSION){
            throw new RuntimeException("获得响应版本不被支持!!!");
        }
        // 3、解析头部长度 2字节 , 校验头部长度
        short headLength = msg.readShort();
        if (headLength != MessageFormatConstant.HEAD_LENGTH){
            throw new RuntimeException("获得请求头部长度不合法!!!");
        }
        // 4、解析总长度 4字节 , 校验总长度
        int fullLength = msg.readInt();

        // 5、解析响应状态码 1字节 , 校验响应状态码
        byte ResponseCode = msg.readByte();

        // 6、解析序列化类型 1字节 , 校验序列化类型
        byte serializeType = msg.readByte();

        // 7、解析压缩类型 1字节 , 校验压缩类型
        byte compressType = msg.readByte();

        // 8、解析请求Id 8字节 , 校验请求Id
        long requestId = msg.readLong();

        // 9、解析时间戳 8字节 , 校验时间戳
        long timeStamp = msg.readLong();

        // ---------------------封装ResponseBody---------------------------------
        YrpcResponse yrpcResponse = YrpcResponse.builder()
                .responseCode(ResponseCode)
                .compressType(compressType)
                .requestId(requestId)
                .serializeType(serializeType)
                .timeStamp(timeStamp)
                .build();

        // 9、解析body
        int bodyLength = fullLength - headLength;
        byte[] ResponseBodyBytes = new byte[bodyLength];
        msg.readBytes(ResponseBodyBytes);
        // 将字节数组进行解压缩、反序列化

        Object ResponseBody = null;

        if (ResponseBodyBytes!=null && ResponseBodyBytes.length != 0){
        // todo 解压缩
        Compress compress = CompressFactory.getCompress(compressType).getImpl();
        byte[] decompressBody = compress.decompress(ResponseBodyBytes);
        // todo 反序列化
        Serialize serialize = SerializerFactory.getSerializer(serializeType).getImpl();
        ResponseBody = serialize.deserialize(decompressBody, Object.class);
        }
        yrpcResponse.setResponseBody(ResponseBody);

        out.add(yrpcResponse);
    }
}
